﻿using System;
using System.Collections.Generic;
using System.Data.Entity;
using System.Linq;
using System.Net;
using System.Web.Mvc;
using MVC.Models;

namespace MVC.Controllers
{
    [Authorize]
    public class BookController : Controller
    {
        private readonly BookContext db = new BookContext();
        
        public ActionResult Index(string indexBy)
        {
            var readBooks = db.BookLists.First(l => l.UserName.Equals(User.Identity.Name)).Books.ToList();
            var books = new List<Book>();

            if (indexBy != null)
            {

                if (indexBy.Equals("Author"))
                {
                    ViewBag.Title = "By Author";
                    books = db.Books.OrderBy(b => b.Author).ToList();
                }
                if (indexBy.Equals("Genre"))
                {
                    ViewBag.Title = "By Genre";
                    books = db.Books.OrderBy(b => b.Genre).ToList();
                }
                if (indexBy.Equals("Title"))
                {
                    ViewBag.Title = "By Title";
                    books = db.Books.OrderBy(b => b.Title).ToList();
                }
            }
            else
            {
                ViewBag.Title = "All Books";
                books = db.Books.ToList();
            }

            if (Session["Message"] != null)
            {
                ViewBag.Message = (string)Session["Message"];
                Session.Remove("Message");
            }

            return View(books.Where(b => readBooks.All(rb => rb.Book.BookId != b.BookId)).ToList());
        }

        public ActionResult Search(string searchTerm)
        {
            var books = new List<Book>();
            if (searchTerm == null)
            {
                searchTerm = (string) Session["searchTerm"];
            }

            var split = searchTerm.Split(new[] { ' ', ',' }, StringSplitOptions.RemoveEmptyEntries);

            foreach (var s in split)
            {
                books.AddRange(db.Books.Where(b => b.Title.Contains(searchTerm)).ToList());
                books.AddRange(db.Books.Where(b => b.Author.Contains(searchTerm)).ToList());
                books.AddRange(db.Books.Where(b => b.Genre.Contains(searchTerm)).ToList());
            }

            books = books.Distinct().ToList();

            var readBooks = db.BookLists.First(l => l.UserName.Equals(User.Identity.Name)).Books.ToList();

            ViewBag.Title = string.Format("Titles, Authors, or Genres containing \"{0}\"", searchTerm);
            Session.Add("searchTerm", searchTerm);
            return View(books.Where(b => readBooks.All(rb => rb.Book.BookId != b.BookId)).ToList());
        }

        // GET: /Book/Details/5
        public ActionResult Details(int? id)
        {
            if (id == null)
            {
                return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
            }
            var book = db.Books.Find(id);
            if (book == null)
            {
                return HttpNotFound();
            }
            return View(book);
        }

        // GET: /Book/Create
        public ActionResult Create()
        {
            return View();
        }

        // POST: /Book/Create
        // To protect from overposting attacks, please enable the specific properties you want to bind to, for 
        // more details see http://go.microsoft.com/fwlink/?LinkId=317598.
        [HttpPost]
        [ValidateAntiForgeryToken]
        public ActionResult Create(
            [Bind(Include = "BookId,Title,Author,Description,Genre,Creator")] Book book)
        {
            if (ModelState.IsValid)
            {
                book.Creator = User.Identity.Name;
                db.Books.Add(book);
                db.SaveChanges();
                return RedirectToAction("Index");
            }

            return View(book);
        }

        // GET: /Book/Edit/5
        public ActionResult Edit(int? id)
        {
            if (id == null)
            {
                return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
            }
            var book = db.Books.Find(id);
            if (book == null)
            {
                return HttpNotFound();
            }

            return View(book);
        }

        // POST: /Book/Edit/5
        // To protect from overposting attacks, please enable the specific properties you want to bind to, for 
        // more details see http://go.microsoft.com/fwlink/?LinkId=317598.
        [HttpPost]
        [ValidateAntiForgeryToken]
        public ActionResult Edit(
            [Bind(Include = "BookId,Title,Author,Description,Genre,Creator")] Book book)
        {
            if (ModelState.IsValid)
            {
                db.Entry(book).State = EntityState.Modified;
                db.SaveChanges();
                return RedirectToAction("Index");
            }

            return View(book);
        }

        protected override void Dispose(bool disposing)
        {
            if (disposing)
            {
                db.Dispose();
            }
            base.Dispose(disposing);
        }

        public ActionResult AddToList(int id, string indexBy)
        {
            var book = db.Books.Find(id);
            var readBook = new ReadBook { Book = book, DateRead = DateTime.Now };
            var bookList = db.BookLists.First(list => list.UserName.Equals(User.Identity.Name));
            bookList.Books.Add(readBook);
            db.ReadBooks.Add(readBook);
            db.Entry(bookList).State = EntityState.Modified;
            db.SaveChanges();

            Session.Add("Message", "Successfully added '" + readBook.Book.Title + "' to your list.");

            return Redirect(Request.UrlReferrer.ToString());

        }
    }
}